import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

import javax.swing.*;

public class Entrance extends JFrame implements ActionListener {
    public final static String basePath = Class.class.getClass().getResource("/").getPath();
    public static int order = 0;

    public static void drawReact(int x, int y, int with, int height, Color color) {
        g.setColor(color);
        g.setStroke(new BasicStroke(3.0f));
        g.drawRect(x + 1, y + 1, with - 1, height - 1);
        try {
            Thread.sleep(speed);
            while (!running){
                if (interrupt)throw new RuntimeException("结束绘制");
                Thread.sleep(speed);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static boolean isValid(int arr[][], int column, int row) {
        display(arr, false);
        drawReact(column * 50, row * 50, 50, 50, Color.green);
        //同行检测[列][行]
        for (int i = column; i >= 0; i--) {
            if (arr[i][row] == 1) {
                drawReact(i * 50, row * 50, 50, 50, Color.red);
                return false;
            }
        }
        //左斜右
        for (int i = column - 1, j = row - 1; i >= 0 && j >= 0; i--, j--) {
            if (arr[i][j] == 1) {
                drawReact(i * 50, j * 50, 50, 50, Color.red);
                return false;
            }
        }
        //右斜左
        for (int i = column - 1; i >= 0 && (column + row - i) < 8; i--) {
            if (arr[i][column + row - i] == 1) {
                drawReact(i * 50, (column + row - i) * 50, 50, 50, Color.red);
                return false;
            }
        }
        return true;
    }

    public static boolean interrupt = false;

    public static void queenTest(int arr[][], int column) {
        if (column > 7) {
            display(arr, true);
            return;
        }

        for (int j = 0; j < 8; j++) {
            try {
                if (isValid(arr, column, j)) {
                    arr[column][j] = 1;
                    queenTest(arr, column + 1);
                    arr[column][j] = 0;
                }
            }catch (RuntimeException e){
                System.out.println(e.getMessage());
                return;
            }
        }
    }

    @Override
    public void paint(Graphics graph) {//系统自带的paint方法,自动调用
        super.paint(graph);
        this.g = (Graphics2D) graph;
        draw8x8();
    }

    public static JLabel orderHint;

    public Entrance() {

        this.setSize(700, 400);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setUndecorated(true);

        JPanel contentPane = (JPanel) this.getContentPane();
        contentPane.setLayout(null);

        //初始化标题和关闭按钮
        JLabel topTitle = new JLabel("八皇后问题");
        topTitle.setFont(new Font("宋体", Font.BOLD, 20));
        topTitle.setForeground(Color.black);
        topTitle.setLocation(500, 20);
        topTitle.setSize(180, 40);
        contentPane.add(topTitle);
        JButton closeBtn = new JButton(new ImageIcon(basePath + "/img/close.png"));
        closeBtn.setOpaque(false);
        closeBtn.setBorder(null);
        closeBtn.setBounds(666,2,32,32);
        closeBtn.addActionListener(e->{
            System.exit(0);
        });
        contentPane.add(closeBtn);

        //初始化拖动条
        JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 20, 10);
        slider.setMajorTickSpacing(10);
        slider.setMinorTickSpacing(1);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.setBounds(460, 120, 180, 50);

        contentPane.add(slider);
        JLabel speedHint = new JLabel("动画速度：10");
        speedHint.setBounds(470, 180, 100, 30);
        contentPane.add(speedHint);
        orderHint = new JLabel("当前演示");
        orderHint.setFont(new Font("宋体", Font.BOLD, 20));
        orderHint.setForeground(Color.MAGENTA);
        orderHint.setBounds(470, 240, 190, 40);
        contentPane.add(orderHint);

        slider.addChangeListener(e -> {
            speed = 2100 - slider.getValue() * 100;
            speedHint.setText("动画速度：" + slider.getValue());
        });
        //初始化按钮
        startBtn = new JButton();
        startBtn.setText("开 始");
        startBtn.setBounds(510, 300, 80, 40);
        contentPane.add(startBtn);

        resumeBtn = new JButton();
        resumeBtn.setBounds(450, 300, 80, 40);
        resumeBtn.setVisible(false);
        contentPane.add(resumeBtn);

        endBtn = new JButton();
        endBtn.setText("结 束");
        endBtn.setBounds(570, 300, 80, 40);
        endBtn.setVisible(false);
        contentPane.add(endBtn);

        //
        startBtn.addActionListener(this);
        resumeBtn.addActionListener(this);
        endBtn.addActionListener(this);

        this.setVisible(true);
    }

    public final static Image icon = new ImageIcon(basePath + "/img/queen.png").getImage();
    public static Graphics2D g;
    public static int speed = 1100;
    public static JButton startBtn;
    public static JButton resumeBtn;
    public static JButton endBtn;
    public static boolean running = false;

    public static void draw8x8() {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                g.setColor((i + j) % 2 == 0 ? Color.WHITE : Color.gray);
                g.fillRect(i * 50, j * 50, 50, 50);
            }
        }
    }

    public static void display(int[][] arr, boolean isFinish) {
        draw8x8();
        if (arr == null) return;

        System.out.println("<------------------------->");
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (arr[j][i] == 1) {
                    g.drawImage(icon, j * 50, i * 50, null);
                }
                System.out.print(arr[j][i] == 1 ? "Q" : "□");
            }
            System.out.println();
        }
        if (isFinish) {
            drawReact(0, 0, 400, 400, Color.green);
            updateOrder();
        }
    }

    public static void updateOrder() {
        String hint="当前演示->第" + ++order + "种";
        System.out.println(hint);
        orderHint.setText(hint);
    }

    public static void main(String[] args) {
        new Entrance();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == startBtn) {
            order = 0;
            running = true;
            interrupt = false;
            updateOrder();
            resumeBtn.setText("暂 停");
            startBtn.setVisible(false);
            resumeBtn.setVisible(true);
            endBtn.setVisible(true);
            g = (Graphics2D) this.getRootPane().getGraphics();
            int[][] arr = new int[8][8];
            new Thread(new Runnable() {
                @Override
                public void run() {
                    queenTest(arr, 0);
                }
            }).start();
        } else if (e.getSource() == resumeBtn) {
            running = !running;
            resumeBtn.setText(running ? "暂 停" : "继 续");
            try {
                Thread.sleep(speed);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        } else if (e.getSource() == endBtn) {
            running = false;
            interrupt = true;
            try {
                Thread.sleep(speed);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            startBtn.setVisible(true);
            resumeBtn.setVisible(false);
            endBtn.setVisible(false);
        }
    }
}
